
package remote;

import java.io.Serializable;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import messaging.InterNodeMessage;

/**
 * An interface for a Remote Distributed Hash Map.
 * 
 * @author Team 04
 * @version 05/06/2013
 */
public interface RemoteDistributedHashMap extends Remote
{
  /**
   * Returns the value corresponding to the specified key in the map.
   * 
   * @param the_key The key.
   * @return The value mapped to the_key.
   * @throws RemoteException if something goes wrong with RMI.
   * @throws AlreadyBoundException
   */
  RemoteFuture get(String the_key) throws RemoteException, AlreadyBoundException;

  /**
   * Puts the specified key-value mapping into the map.
   * 
   * @param the_key stores the key.
   * @param the_value stores the value corresponding to the key.
   * @return the previous value that was mapped to the key, if any.
   * @throws RemoteException if something goes wrong with RMI.
   * @throws AlreadyBoundException 
   */
  RemoteFuture put(String the_key, Serializable the_value) throws RemoteException, AlreadyBoundException;

  /**
   * Removes the specified key-value mapping from the map.
   * 
   * @param the_key stores the key.
   * @return the previous value that was mapped to the key, if any.
   * @throws RemoteException if something goes wrong with RMI.
   */
  RemoteFuture remove(String the_key) throws RemoteException, AlreadyBoundException;
 /**
  * @throws RemoteException if there is a problem completing the method call.
  * @throws InterruptedException 
  */
  void send(InterNodeMessage message) throws RemoteException, InterruptedException;
  
  
  void removeNode() throws AccessException, RemoteException, NotBoundException, InterruptedException;
  

  /**
   * This function will return the first key in the ring.
   * @return  a remote object of firstkey
   * @throws AccessException  if something goes wrong with RMI
   * @throws RemoteException  if something goes wrong with RMI
   * @throws NotBoundException  if something goes wrong with RMI
   * @throws InterruptedException  if something goes wrong with RMI
   */
  RemoteFuture firstKey() throws AccessException, RemoteException, NotBoundException, InterruptedException;
  
  /**
   * This function will return the last key in the ring.
   * @return  a remote object of lastkey
   * @throws AccessException  if something goes wrong with RMI
   * @throws RemoteException  if something goes wrong with RMI
   * @throws NotBoundException  if something goes wrong with RMI
   * @throws InterruptedException  if something goes wrong with RMI
   */
  RemoteFuture lastKey() throws AccessException, RemoteException, NotBoundException, InterruptedException;
  
  /**
   * This function will return the total key numbers in the ring.
   * @return  a remote object of total key numbers
   * @throws AccessException  if something goes wrong with RMI
   * @throws RemoteException  if something goes wrong with RMI
   * @throws NotBoundException  if something goes wrong with RMI
   * @throws InterruptedException  if something goes wrong with RMI
   */
  RemoteFuture totalCount() throws AccessException, RemoteException, NotBoundException, InterruptedException;
  
  /**
   * This function will return the actual node in the ring.
   * @return  a remote object of actual node name
   * @throws AccessException  if something goes wrong with RMI
   * @throws RemoteException  if something goes wrong with RMI
   * @throws NotBoundException  if something goes wrong with RMI
   * @throws InterruptedException  if something goes wrong with RMI
   */
  RemoteFuture actualCount() throws AccessException, RemoteException, NotBoundException, InterruptedException;
  public boolean isrebalancing() throws RemoteException;
}
